/**
 * 
 */
package luzhin;

import java.util.*;

import luzhin.frames.*;

/**
 * The main class. Creates a game, observes it and updates the frame.
 * 
 * @author lacungus
 *
 */
public class StandaloneLuzhin implements Observer {

	// strategy ids
	public static final int MANUAL = 1;
	public static final int BACKTRACK = 2;
	
	public static final int WHITE = 1;
	public static final int BLACK = -1;
	public static final int NONE = 0;
	
	/**
	 * 
	 */
	public StandaloneLuzhin() {
	}
	
	private static StandaloneLuzhin chesster;
	private MainFrame mainFrame;
	private Game game;
	private AbstractMainFrameController controller;
	
	public Game getGame() {
		return game;
	}
	
	/**
	 * The board in the game was updated, so we need to redraw the frame. 
	 */
	public void update(Observable observer, Object o) {
		controller.redraw(game);
	}

	/**
	 * 
	 * @return class instance.
	 */
	public static StandaloneLuzhin getChesster() {
		return chesster;
	}
	
	/**
	 * Creates frame and runs a game.
	 */
	public void run() {
		mainFrame = new ButtonFrame();
		mainFrame.initDraw();
		controller = new ButtonFrameController();		
		controller.setFrame(mainFrame);
		
		Strategy whiteStrategy = null;
		Strategy blackStrategy = null;
		
		InitDialogController initDialogController = new InitDialogController();		
		new InitDialog(mainFrame, initDialogController);

		int whiteStrategyId = initDialogController.getWhiteStrategyId();
		int blackStrategyId = initDialogController.getBlackStrategyId();
		
		switch (whiteStrategyId) {
		case (MANUAL) : {
			whiteStrategy = new ManualStrategy(controller);
			break;
		}
		case (BACKTRACK) : {
			whiteStrategy = new BacktrackStrategy(new SimpleMoveGenerator(), new AdvancedEvaluator());
			break;
		}
		}

		switch (blackStrategyId) {
		case (MANUAL) : {
			blackStrategy = new ManualStrategy(controller);
			break;
		}
		case (BACKTRACK) : {
			blackStrategy = new BacktrackStrategy(new SimpleMoveGenerator(), new AdvancedEvaluator());
			break;
		}
		}
		
		String path = initDialogController.getGameToLoadString();
		if (path == null) {
			game = new Game(whiteStrategy, blackStrategy);
		} else {
			try {
				game = Game.load(path);
				game.setWhiteStrategy(whiteStrategy);
				game.setBlackStrategy(blackStrategy);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		mainFrame.setAlwaysOnTop(true);
		controller.redraw(this.game);
		mainFrame.update(mainFrame.getGraphics());
		game.addObserver(this);
		
		BoardPool.initPool();
		game.run();
	}
	
	public static void main(String[] args) {
		chesster = new StandaloneLuzhin();
		chesster.run();
	}
	
}
